package cn.jimmie.learn.viewArt.refreshview;

import android.annotation.SuppressLint;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.ListView;

import cn.jimmie.learn.viewArt.refreshview.core.CommonDecorHolder;
import cn.jimmie.learn.viewArt.refreshview.core.ContentView;
import cn.jimmie.learn.viewArt.refreshview.core.DecorHolder;
import cn.jimmie.learn.viewArt.refreshview.core.Listview.ListContentView;
import cn.jimmie.learn.viewArt.refreshview.core.OnViewAnimatorEvent;
import cn.jimmie.learn.viewArt.refreshview.core.RefreshSource;
import cn.jimmie.learn.viewArt.refreshview.core.RefreshState;
import cn.jimmie.learn.viewArt.refreshview.core.TouchDispatcher;
import cn.jimmie.learn.viewArt.refreshview.core.recyclerview.RecyclerContentView;
import cn.jimmie.learn.viewArt.refreshview.core.scrollview.RefreshScrollView;
import cn.jimmie.learn.viewArt.refreshview.core.scrollview.ScrollContentView;

/**
 * function :
 *
 * <p> Create Time:  2019年04月10日 15:18 </p>
 * <p> @author Jimmie.Qian  </p>
 */
public class RefreshLayout extends LinearLayout implements RefreshSource,
        TouchDispatcher.OnRefreshTouchListener, ContentView.OnFootLocationListener, View.OnClickListener {

    private DecorHolder mHolder;
    private RefreshState mStatus;
    private OnRefreshListener mListener;
    private ContentView mContentView;
    private TouchDispatcher mDispatcher;

    public RefreshLayout(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public RefreshLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        setOrientation(LinearLayout.VERTICAL);
        mStatus = new RefreshState();
        mHolder = new CommonDecorHolder(context);

        View headerView = mHolder.getHeadView();
        addView(headerView, 0);
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();

        int count = getChildCount();
        for (int i = 0; i < count; i++) {
            View child = getChildAt(i);
            if (child instanceof ListView) {
                mContentView = new ListContentView(child, mStatus);
                break;
            } else if (child instanceof RecyclerView) {
                mContentView = new RecyclerContentView(child, mStatus);
            } else if (child instanceof RefreshScrollView) {
                mContentView = new ScrollContentView(child, mStatus);
            } else continue;
            break;
        }

        if (mContentView == null) {
            throw new RuntimeException("cant find such a support view, like <ListView> , <RecyclerView> or <ScrollContentView>");
        }

        mContentView.setOnFooterLocationListener(this);
        mContentView.setFooterVisibility(mHolder.getFootView(), View.INVISIBLE);
        mHolder.getFootView().setOnClickListener(this);

        mDispatcher = new TouchDispatcher(this);
        mDispatcher.setTouchListener(this);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent e) {
        return mDispatcher.handleInterceptTouchEvent(e);
    }

    @Override
    @SuppressLint("ClickableViewAccessibility")
    public boolean onTouchEvent(MotionEvent event) {
        return mDispatcher.handleTouchEvent(event);
    }

    public void stopPullRefresh() {
        mStatus.setLoadState(RefreshState.LoadState.IDLE);
        mHolder.onHeaderRefreshFinish();
        mHolder.startHeaderAnimation(false);
    }

    public void stopLoadMore(RefreshState.ResultState state) {
        if (!mStatus.isFootViewEnable()) return;

        setLoadMoreState(state);
        mHolder.onFooterLoadFinish(state);
    }

    public void setLoadMoreState(RefreshState.ResultState state) {
        if (!mStatus.isFootViewEnable()) return;

        if (state == RefreshState.ResultState.FAILURE) {
            mHolder.getFootView().setEnabled(true);
        } else mHolder.getFootView().setEnabled(false);

        if (state == RefreshState.ResultState.SUCCESS) {
            mContentView.setFooterVisibility(mHolder.getFootView(), View.INVISIBLE);
        }
        mStatus.setResultState(state);
        mStatus.setLoadState(RefreshState.LoadState.IDLE);
    }

    public void setOnRefreshListener(OnRefreshListener listener) {
        mListener = listener;
    }

    public void setFootViewEnable(boolean enable) {
        mStatus.setFootViewEnable(enable);
    }

    public void setHeadViewEnable(boolean enable) {
        mStatus.setHeadViewEnable(enable);
    }

    @Override
    public RefreshState getState() {
        return mStatus;
    }

    @Override
    public boolean isTopPosition() {
        return mContentView.isTopPosition();
    }

    @Override
    public int getHeaderHeight() {
        return mHolder.getHeadView().getHeight();
    }

    @Override
    public int getHeaderTopMargin() {
        return mHolder.getHeaderTopMargin();
    }

    @Override
    public OnViewAnimatorEvent getViewEvent() {
        return mHolder;
    }

    @Override
    public void onHeaderTouchPulling(int distance) {
        mHolder.requestHeaderLayout((distance / 2) - getHeaderHeight());
    }

    @Override
    public void onHeaderTouchRelease(boolean needRefresh) {
        mHolder.startHeaderAnimation(true);
        if (needRefresh && mListener != null)
            mListener.onPullRefresh();
    }

    @Override
    public void onFooterRefresh() {
        mContentView.setFooterVisibility(mHolder.getFootView(), View.VISIBLE);
        mHolder.onFooterLoading();
        if (mListener != null) mListener.onLoadMore();
    }

    @Override
    public void onClick(View v) {
        if (v != mHolder.getFootView()) return;
        if (mStatus.getResultState() == RefreshState.ResultState.FAILURE) {
            onFooterRefresh();
        }
    }

    public interface OnRefreshListener {

        void onPullRefresh();

        void onLoadMore();
    }
}
